<style>
.orange-row {
  background: #eca56b !important;
}
.green-row {
  background: #bcfa7a !important;
}
</style>
<template>
  <div class="execution">
    <basic-container>
      <div ref="tableWrapper">
        <avue-crud
          ref="crud"
          :key="crudKey"
          :page.sync="page"
          :data="tableData"
          :table-loading="tableLoading"
          :option="option"
          :span-method="spanMethod"
          :header-cell-class-name="headerCellClassName"
          @on-load="getList"
          @search-change="searchChange"
          @refresh-change="refreshChange"
          @size-change="sizeChange"
          @current-change="currentChange"
        >
          <template slot="menuLeft">
            <el-button type="primary" @click="prevMonth">上个月</el-button>
            <el-button type="primary" @click="nextMonth">下个月</el-button>
          </template>
        </avue-crud>
      </div>
    </basic-container>
  </div>
</template>

<script>
import { workOrderScheduleSummaryPage } from "@/api/workorder/workorderschedulemain";
export default {
  data() {
    return {
      crudKey: 0, // 新增一个 key 值
      tableData: [],
      page: {
        total: 0, // 总页数
        currentPage: 1, // 当前页数
        pageSize: 20, // 每页显示多少条
      },
      tableLoading: false,
      option: {
        headerAlign: "center",
        align: "center",
        border: true,
        index: true,
        indexLabel: "序号",
        menu: false,
        addBtn: false,
        height: "60vh",
        searchMenuSpan: 4,
        searchEnter: true,
        indexMethod: this.indexMethod, // 自定义序号列的显示内容
        searchSpan: 5, // 设置每个搜索框的宽度占比
        searchStyle: { width: "150px" }, // 设置搜索框的宽度
        column: [
          /*          {
            label: '工厂',
            prop: 'factory',
            fixed: true,
            width: 40,
          },*/
          {
            label: "客户代码",
            prop: "customerCode",
            fixed: true,
            search: true,
            width: 50,
            inputStyle: {
              width: "200px", // 设置输入框的宽度
            },
          },
          {
            label: "客户订单号",

            prop: "customerDocNo",
            fixed: true,
            search: true,
            width: 50,
            searchLabelWidth: 100,
            inputStyle: {
              width: "200px", // 设置输入框的宽度
            },
          },
          {
            label: "客户 PO",
            prop: "customerPO",
            fixed: true,
            width: 50,
          },
          {
            label: "成品品号",
            prop: "itemCode",
            fixed: true,
            width: 50,
          },
          {
            label: "订单数量",
            prop: "orderQty",
            fixed: true,
            width: 60,
          },
          {
            label: "出货日期",
            prop: "deliveryDate",
            fixed: true,
            width: 50,
          },
          {
            label: "工单号",
            prop: "docNo",
            fixed: true,
            width: 60,
            search: true,
            inputStyle: {
              width: "200px", // 设置输入框的宽度
            },
          },
          {
            label: "工单数量",
            prop: "docNoQty",
            fixed: true,
            width: 60,
          },
          {
            label: "工单状态",
            prop: "moStatus",
            fixed: true,
            type: "select",
            width: 60,
            dicUrl: "/admin-api/system/dict-data/type?type=workorder_status",
            props: {
              label: "label",
              value: "value",
            },
            search: true,
            inputStyle: {
              width: "200px", // 设置输入框的宽度
            },
            dicMethod: "get",
            html: true, //配置html设置为true即可支持formatter转义html代码
            formatter: (val) => {
              if (val.moStatus == "未生产") {
                return '<b style="color:red">未生产</b>';
              } else if (val.moStatus == "生产中") {
                return '<b style="color:green">生产中</b>';
              } else if (val.moStatus == "指定完工") {
                return '<b style="color:orange">指定完工</b>';
              } else if (val.moStatus == "已完工") {
                return '<b style="color:rgba(68,68,68,0.73)">已完工</b>';
              } else if (val.moStatus == "已发料") {
                return '<b style="color:rgba(221,31,132,0.73)">已发料</b>';
              }
            },
          },
          {
            label: "完成数量",
            prop: "completedQty",
            fixed: true,
            width: 60,
            formatter: (val) => {
              if (val.completedQty == null) {
                return "--";
              }
              return val.completedQty;
            },
          },
          {
            label: "入库数量",
            prop: "storageQty",
            fixed: true,
            width: 60,
          },
          {
            label: "未入库数量",
            prop: "unStorageQty",
            fixed: true,
            width: 60,
          },
          {
            label: "线体",
            prop: "lineName",
            fixed: true,
            width: 60,
          },
          {
            label: "排产计划合计",
            prop: "productionPlanTotal",
            fixed: true,
            width: 60,
          },
          {
            label: "实际产出合计",
            prop: "actualOutputTotal",
            fixed: true,
            width: 60,
          },
          {
            label: "生产掉数合计",
            prop: "productionLossTotal",
            fixed: true,
            width: 60,
          },
          {
            label: "计划排产信息",
            headerAlign: "left",
            children: this.generateDateColumns(),
          },
        ],
      },
      currentDateIndex: 0, // 记录当前日期的索引
      currentDate: new Date(), // 当前显示的日期
      weekDayAndList: [], //存储几月几日以及对应的日期
    };
  },
  watch: {
    tableData: {
      handler(newVal) {
        this.calculateSpans();
      },
      deep: true,
    },
  },
  created() {
    console.log(this.currentDate);
  },
  mounted() {
    const dateColumns = this.generateDateColumns();
    // 在表格渲染完成后滚动到当前日期位置
    this.$nextTick(() => {
      const tableHeaderWrapper = this.$refs.tableWrapper.querySelector(
        ".el-table__header-wrapper"
      );
      const tableBodyWrapper = this.$refs.tableWrapper.querySelector(
        ".el-table__body-wrapper"
      );
      if (tableHeaderWrapper) {
        const cellWidth = 180; // 假设每个日期单元格宽度为 100px，可根据实际情况调整
        tableHeaderWrapper.scrollLeft = this.currentDateIndex * cellWidth;
        tableBodyWrapper.scrollLeft = this.currentDateIndex * cellWidth;
      }
      const eltablefixed = this.$refs.tableWrapper.querySelector(
        ".el-table__fixed, .el-table__fixed-right"
      );
      if (eltablefixed) {
        console.log(eltablefixed.style);
        const style = eltablefixed.style;
        console.log("width", style.height);
        eltablefixed.style.height = 535 + "px";
      }
    });
  },

  methods: {
    // 列表查询
    getList(page, params) {
      this.tableLoading = true;
      workOrderScheduleSummaryPage(
        Object.assign(
          {
            current: page.currentPage,
            size: page.pageSize,
          },
          params,
          this.searchForm
        )
      )
        .then((response) => {
          const dateColumns = this.generateDateColumns();
          var data = response.data.data.records;
          for (let i = 0; i < data.length; i++) {
            var details = data[i].workorderScheduleDetailsList;
            for (let j = 0; j < details.length; j++) {
              const scheduleTime = details[j].scheduleTime; //排产时间格式为YYYY-MM-DD
              // 创建 Date 对象
              const date = new Date(scheduleTime);
              // 获取月份和日期
              const month = date.getMonth() + 1; // getMonth() 返回 0-11，所以需要加 1
              const day = date.getDate();
              // 组合成 MM月DD号 格式
              const formattedDate = `${month}月${day}日`;
              // 为动态日期列添加数据
              dateColumns.forEach((weekDayColumn) => {
                weekDayColumn.children.forEach((dateColumn) => {
                  const dateStr = dateColumn.label;
                  if (dateStr === formattedDate) {
                    if (
                      details[j].planQty === 0 &&
                      details[j].completeQty === 0 &&
                      details[j].differenceQty === 0
                    ) {
                      data[i][`plan_${dateStr}`] = null;
                      data[i][`actual_${dateStr}`] = null;
                      data[i][`difference_${dateStr}`] = null;
                    } else {
                      data[i][`plan_${dateStr}`] = details[j].planQty;
                      data[i][`actual_${dateStr}`] = details[j].completeQty;
                      data[i][`difference_${dateStr}`] =
                        details[j].differenceQty;
                    }
                  }
                });
              });
            }
          }
          this.tableData = data;
          this.page.total = response.data.data.total;
          this.tableLoading = false;
        })
        .catch(() => {
          this.tableLoading = false;
        });
    },
    // 每页条数改变事件
    sizeChange(pageSize) {
      this.page.pageSize = pageSize;
    },
    // 当前页发生改变事件
    currentChange(current) {
      this.page.currentPage = current;
    },
    // 查询事件
    searchChange(form, done) {
      this.searchForm = form;
      this.page.currentPage = 1;
      this.getList(this.page, form);
      done();
    },
    // 刷新事件
    refreshChange() {
      this.getList(this.page);
    },
    generateDateColumns() {
      this.createCurrentDate();
      const year = this.currentDate.getFullYear();
      const month = this.currentDate.getMonth();
      const firstDay = new Date(year, month, 1);
      const lastDay = new Date(year, month + 1, 0);
      const weekDays = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
      const columns = [];
      const today = new Date();
      let index = 0;
      let weekDayAndList = [];
      for (
        let day = new Date(firstDay);
        day <= lastDay;
        day.setDate(day.getDate() + 1)
      ) {
        const weekDay = weekDays[day.getDay()];
        const dateStr = `${day.getMonth() + 1}月${day.getDate()}日`;
        weekDayAndList.push({
          weekDay: weekDay,
          dateStr: dateStr,
        });
        columns.push({
          label: weekDay,
          children: [
            {
              label: dateStr,
              children: [
                {
                  label: "计划",
                  prop: `plan_${dateStr}`,
                  width: 60,
                },
                {
                  label: "实际",
                  prop: `actual_${dateStr}`,
                  width: 60,
                },
                {
                  label: "差异",
                  prop: `difference_${dateStr}`,
                  width: 60,
                },
              ],
            },
          ],
        });
        if (
          day.getDate() === today.getDate() &&
          day.getMonth() === today.getMonth() &&
          day.getFullYear() === today.getFullYear()
        ) {
          this.currentDateIndex = index;
        }
        index++;
      }
      this.weekDayAndList = weekDayAndList;
      return columns;
    },
    /* calculateSpans() {
      const columns = this.option.column; // 获取表格列配置
      this.spans = {}; // 初始化 spans 对象，用于存储每列的合并信息
      columns.forEach(column => { // 遍历每一列
        const prop = column.prop || column.property; // 获取列的属性名（prop 或 property）
        this.spans[prop] = this.rowSpan(prop); // 计算该列的合并信息，并存储在 spans 对象中
      });
    },
    rowSpan(prop) {
      let list = []; // 初始化一个数组，用于存储每行的合并信息
      let position = 0; // 初始化位置指针，用于记录当前合并段的起始位置
      this.tableData.forEach((item, index) => { // 遍历表格数据
        if (index === 0) {
          list.push(1); // 第一行默认合并值为1
        } else {
          if (this.tableData[index][prop] === this.tableData[index - 1][prop]) {
            list[position] += 1; // 如果当前行与前一行相同，则增加合并值
            list.push(0); // 当前行被合并，设置为0
          } else {
            list.push(1); // 如果不同，则当前行不合并，设置为1
            position = index; // 更新位置指针到当前行
          }
        }
      });
      return list; // 返回合并信息列表
    },
    spanMethod({ row, column, rowIndex, columnIndex }) {
      // 定义不需要合并的列的属性名
      const noMergeColumns = [ 'lineName', 'productionPlanTotal', 'actualOutputTotal', 'productionLossTotal'];
      console.log(row);
      // 排除操作列和序号列
      if (column.label === '操作'  || column.type === 'index' || columnIndex>17) {
        return {
          rowspan: 1,
          colspan: 1
        };
      }


      // 获取当前列的属性名
      const prop = column.prop || column.property;

      // 如果当前列在不需要合并的列范围内，则不进行合并
      if (noMergeColumns.includes(prop)) {
        return {
          rowspan: 1,
          colspan: 1
        };
      }
      // 检查当前单元格的数据是否为空
      if (row[prop] === null || row[prop] === undefined || row[prop] === '') {
        return {
          rowspan: 1,
          colspan: 1
        };
      }
      // 继续执行原有的合并逻辑
      if (this.spans[prop]) {
        const _row = this.spans[prop][rowIndex];
        const _col = _row > 0 ? 1 : 0;
        return {
          rowspan: _row,
          colspan: _col
        };
      }
      return {};
    },*/
    calculateSpans() {
      const columns = this.option.column; // 获取表格列配置
      this.spans = {}; // 初始化 spans 对象，用于存储每列的合并信息
      this.indexRanges = {}; // 初始化 indexRanges 对象，用于存储序号列的合并范围
      columns.forEach((column) => {
        // 遍历每一列
        const prop = column.prop || column.property; // 获取列的属性名（prop 或 property）
        if (prop === "index") {
          this.spans[prop] = this.rowSpanForIndex(); // 计算序号列的合并信息
        } else if (prop === "factory") {
          this.spans[prop] = this.rowSpanForFactory(); // 计算工厂列的合并信息
        } else if (prop === "docNo") {
          this.spans[prop] = this.rowSpanForDocNo(); // 计算工单号列的合并信息
        } else if (
          [
            "moStatus",
            "completedQuantity",
            "storageQty",
            "unStorageQty",
          ].includes(prop)
        ) {
          this.spans[prop] = this.rowSpanBasedOnDocNo(prop); // 计算工单状态、完成数量、入库数量、未入库数量列的合并信息
        } else {
          this.spans[prop] = this.rowSpan(prop); // 计算该列的合并信息，并存储在 spans 对象中
        }
      });
    },
    rowSpan(prop) {
      let list = []; // 初始化一个数组，用于存储每行的合并信息
      let position = 0; // 初始化位置指针，用于记录当前合并段的起始位置
      this.tableData.forEach((item, index) => {
        // 遍历表格数据
        if (index === 0) {
          list.push(1); // 第一行默认合并值为1
        } else {
          if (this.tableData[index][prop] === this.tableData[index - 1][prop]) {
            list[position] += 1; // 如果当前行与前一行相同，则增加合并值
            list.push(0); // 当前行被合并，设置为0
          } else {
            list.push(1); // 如果不同，则当前行不合并，设置为1
            position = index; // 更新位置指针到当前行
          }
        }
      });
      return list; // 返回合并信息列表
    },
    rowSpanForIndex() {
      let list = []; // 初始化一个数组，用于存储每行的合并信息
      let position = 0; // 初始化位置指针，用于记录当前合并段的起始位置
      let indexRanges = []; // 初始化 indexRanges 数组，用于存储序号列的合并范围
      this.tableData.forEach((item, index) => {
        // 遍历表格数据
        if (index === 0) {
          list.push(1); // 第一行默认合并值为1
          indexRanges.push({ start: 1, end: 1 });
        } else {
          if (item.itemCode === this.tableData[index - 1].itemCode) {
            list[position] += 1; // 如果当前行与前一行的品号相同，则增加合并值
            list.push(0); // 当前行被合并，设置为0
            indexRanges[position].end = index + 1; // 更新合并范围的结束位置
          } else {
            list.push(1); // 如果不同，则当前行不合并，设置为1
            position = index; // 更新位置指针到当前行
            indexRanges.push({ start: index + 1, end: index + 1 });
          }
        }
      });
      this.indexRanges = indexRanges; // 存储序号列的合并范围
      return list; // 返回合并信息列表
    },
    rowSpanForFactory() {
      let list = []; // 初始化一个数组，用于存储每行的合并信息
      let position = 0; // 初始化位置指针，用于记录当前合并段的起始位置
      this.tableData.forEach((item, index) => {
        // 遍历表格数据
        if (index === 0) {
          list.push(1); // 第一行默认合并值为1
        } else {
          if (item.itemCode === this.tableData[index - 1].itemCode) {
            list[position] += 1; // 如果当前行与前一行的品号相同，则增加合并值
            list.push(0); // 当前行被合并，设置为0
          } else {
            list.push(1); // 如果不同，则当前行不合并，设置为1
            position = index; // 更新位置指针到当前行
          }
        }
      });
      return list; // 返回合并信息列表
    },
    rowSpanForDocNo() {
      let list = []; // 初始化一个数组，用于存储每行的合并信息
      let position = 0; // 初始化位置指针，用于记录当前合并段的起始位置
      this.tableData.forEach((item, index) => {
        // 遍历表格数据
        if (index === 0) {
          list.push(1); // 第一行默认合并值为1
        } else {
          if (item.docNo === this.tableData[index - 1].docNo) {
            list[position] += 1; // 如果当前行与前一行的工单号相同，则增加合并值
            list.push(0); // 当前行被合并，设置为0
          } else {
            list.push(1); // 如果不同，则当前行不合并，设置为1
            position = index; // 更新位置指针到当前行
          }
        }
      });
      return list; // 返回合并信息列表
    },
    rowSpanBasedOnDocNo(prop) {
      let list = []; // 初始化一个数组，用于存储每行的合并信息
      let position = 0; // 初始化位置指针，用于记录当前合并段的起始位置
      this.tableData.forEach((item, index) => {
        // 遍历表格数据
        if (index === 0) {
          list.push(1); // 第一行默认合并值为1
        } else {
          if (item.docNo === this.tableData[index - 1].docNo) {
            list[position] += 1; // 如果当前行与前一行的工单号相同，则增加合并值
            list.push(0); // 当前行被合并，设置为0
          } else {
            list.push(1); // 如果不同，则当前行不合并，设置为1
            position = index; // 更新位置指针到当前行
          }
        }
      });
      return list; // 返回合并信息列表
    },
    spanMethod({ row, column, rowIndex, columnIndex }) {
      // 定义不需要合并的列的属性名
      const noMergeColumns = [
        "lineName",
        "productionPlanTotal",
        "actualOutputTotal",
        "productionLossTotal",
      ];
      // 排除操作列和序号列
      if (
        column.label === "操作" ||
        column.type === "index" ||
        columnIndex > 16
      ) {
        return {
          rowspan: 1,
          colspan: 1,
        };
      }

      // 获取当前列的属性名
      const prop = column.prop || column.property;

      // 如果当前列在不需要合并的列范围内，则不进行合并
      if (noMergeColumns.includes(prop)) {
        return {
          rowspan: 1,
          colspan: 1,
        };
      }

      // 检查当前单元格的数据是否为空
      if (row[prop] === null || row[prop] === undefined || row[prop] === "") {
        return {
          rowspan: 1,
          colspan: 1,
        };
      }

      // 继续执行原有的合并逻辑
      if (this.spans[prop]) {
        const _row = this.spans[prop][rowIndex];
        const _col = _row > 0 ? 1 : 0;
        return {
          rowspan: _row,
          colspan: _col,
        };
      }
      return {};
    },
    // 自定义序号列的显示内容
    indexMethod(index) {
      const range = this.indexRanges[index];
      if (range && range.start === range.end) {
        return range.start;
      } else if (range) {
        return `${range.start}-${range.end}`;
      }
      return index + 1;
    },
    headerCellClassName({ column, columnIndex, row, rowIndex }) {
      if (columnIndex > 16 && rowIndex === 0) {
        return "orange-row";
      }

      if (
        columnIndex >= 0 &&
        rowIndex === 1 &&
        column.label !== "周六" &&
        column.label !== "周日"
      ) {
        return "orange-row";
      } else if (
        columnIndex >= 0 &&
        rowIndex === 1 &&
        (column.label === "周六" || column.label === "周日")
      ) {
        return "green-row";
      }

      if (columnIndex >= 0 && rowIndex === 2) {
        //根据column.label找到this.weekDayAndList里面的dateStr然后判断对应的weekDay是不是周六周日
        if (
          this.weekDayAndList.find((item) => item.dateStr === column.label)
            .weekDay === "周六" ||
          this.weekDayAndList.find((item) => item.dateStr === column.label)
            .weekDay === "周日"
        ) {
          return "green-row";
        } else {
          return "orange-row";
        }
      }
      if (columnIndex >= 0 && rowIndex === 3) {
        if (
          this.weekDayAndList.find((item) =>
            column.property.includes(item.dateStr)
          ).weekDay === "周六" ||
          this.weekDayAndList.find((item) =>
            column.property.includes(item.dateStr)
          ).weekDay === "周日"
        ) {
          return "green-row";
        } else {
          return "orange-row";
        }
      }
    },
    createCurrentDate() {
      if (this.validatenull(this.currentDate)) {
        this.currentDate = new Date();
      }
    },
    // 上个月按钮点击事件
    prevMonth() {
      this.currentDate.setMonth(this.currentDate.getMonth() - 1);
      this.updateDateColumns();
    },
    // 下个月按钮点击事件
    nextMonth() {
      this.currentDate.setMonth(this.currentDate.getMonth() + 1);
      this.updateDateColumns();
    },
    // 更新日期列并重新加载数据
    updateDateColumns() {
      // 重新生成日期列
      const dateColumns = this.generateDateColumns();

      // 找到计划排产信息列并更新其子列
      const scheduleColumnIndex = this.option.column.findIndex(
        (column) => column.label === "计划排产信息"
      );
      if (scheduleColumnIndex !== -1) {
        // this.option.column[scheduleColumnIndex].children = dateColumns;
        this.$set(
          this.option.column[scheduleColumnIndex],
          "children",
          dateColumns
        );
      }

      // 增加 key 值，强制刷新组件
      this.crudKey++;
      // 重新加载数据
      this.getList(this.page);

      // 在表格渲染完成后滚动到当前日期位置
      /*  this.$nextTick(() => {
        const tableHeaderWrapper = this.$refs.tableWrapper.querySelector('.el-table__header-wrapper');
        const tableBodyWrapper = this.$refs.tableWrapper.querySelector('.el-table__body-wrapper')
        if (tableHeaderWrapper) {
          const cellWidth = 180; // 假设每个日期单元格宽度为 100px，可根据实际情况调整
          tableHeaderWrapper.scrollLeft = this.currentDateIndex * cellWidth;
          tableBodyWrapper.scrollLeft = this.currentDateIndex * cellWidth;
        }
      });*/
    },
  },
};
</script>

<style scoped>
/* 设置表格容器样式 */
.table-container {
  width: 100%;
  overflow-x: auto; /* 当内容宽度超过容器宽度时显示水平滚动条 */
  min-width: 800px; /* 设置最小宽度，可根据实际情况调整 */
}

/* 确保表头容器高度正常，可拖动 */
::v-deep .el-table__header-wrapper {
  min-height: 40px;
}
.button-container {
  margin-bottom: 10px;
}

/deep/ .el-table__body-wrapper {
  z-index: 2;
}
</style>
